学习笔记 QT之Graphic图形编辑器

您所在的位置:网站首页 qt 设置鼠标 学习笔记 QT之Graphic图形编辑器

学习笔记 QT之Graphic图形编辑器

2023-02-22 03:25| 来源: 网络整理| 查看: 265

注:本人学习阶段,仅供参考。如有错误,请指正,谢谢!

一、简单介绍GraphicsView框架

        Graphics View框架实现了模型到视图结构的图形管理,能对大量图元进行管理,支持坐标变换和图元组等多种方便的功能。

框架结构三个主要的类:

1)场景类:QGraphicsScene类(管理多个图形项,用于放置图元的容器,但本身不可见)

2)视图类:QGraphicsView类(提供可视窗口,显示场景中的图元,一个场景中有多个视图)

3)图元类:QGraphicsItem类(各个图元的基础类,QT提供了常用图元的标准类)

三元素关系

        QGraphicsItem(图形项) -----addItem()------>QGraphicsScene(图形项的容器,场景)--------setScene()------>QGraphicsView(可视化使场景中的内容)

三元素坐标系

         QGraphicsView提供QGraphicsView::mapToScene()和QGraphicsView:: mapFromScene()函数用于视图与场景的坐标进行转换

QT提供常用图元标准类

        当然,也可以在QGraphicsItem类的基础上实现自定义的图元类,即用户可以继承QGraphicsItem实现符合自己需要的图元。

QGraphicsLineItem    用来绘制直线,可以通过setLine(const QLineF&)来添加。QGraphicsRectItem    用来绘制矩形,通过setRect()来进行添加QGraphicsEllipseItem    用来绘制椭圆,或者部分椭圆。通过设置setStartAngle(int)和setSpanAngle(int)可以绘制椭圆的一部分。设置的值是1度的1/16。QGraphicsPolygonItem    用来绘制多边形,通过setPolygon()添加QGraphicsPathItem    绘制一个路径,通过setPath()来进行添加QGraphicsSimpleTextItem    绘制简单文本,除了可以设置字体以外,不支持其它的富文本样式QGraphicsTextItem    绘制格式化的文本,可以通过setHtml()或者setDocument()设置html,还可以添加有交互内容的URL超链接。QGraphicsPixmapItem    绘制图片,或者渲染一个图片QGraphicsProxyWidget    绘制任意的QWdiget控件,视图框架允许我们与添加的控件进行交互。  二、Graphic图形编辑器

        这是一个简单的图形编辑器,它只对视图部分进行了部分重写。添加了各种图元,如圆、椭圆、矩形、文本、图片等,可进行旋转、放大、缩小、前置、后置、组合、散开、删除等功能。

        在代码中有很多地方添加了注释,这里就不一一赘述了。

效果展示:

 源码展示:

ui界面:

mainwindow.h

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT private: static const int ItemId = 1; //绘图项自定义数据的key static const int ItemDesciption = 2;//绘图自定义数据的key int seqNum = 0; int backZ = 0; int frontZ = 0; // bool isMode = true; QPoint linePoint; //直线 bool isline = true; //矩形 bool isrectangle = true; //三角形 bool isTriangle = true; //椭圆 bool isEllipse= true; QGraphicsScene *scene; //显示各种坐标 QLabel *labViewCord; //视图 QLabel *labSceneCord; //场景 QLabel *labItemCord; //图元 QLabel *labItemInfo; QPoint actPoint; public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void initview(); void initSlots(); void wheelEvent(QWheelEvent *event); //滑轮 private slots: void onMouseMovePoint(QPoint ponit); //接收鼠标移动传过来的坐标槽函数 void onMouseClicked(QPoint point); //接收鼠标点击传过来的坐标槽函数 void onMouseRightClicked(QPoint point); //接收鼠标右击传过来的坐标槽函数 void actionTrigger(QAction *act); //菜单槽函数 void onMouseDoubleClick(QPoint point); //接收鼠标双击传过来的坐标槽函数 void onKeyPress(QKeyEvent *event); //接收按键传过来的按键槽函数 //画图的槽函数 void drawPressLine(QPoint point); void drawReleaseLine(QPoint point); void onDrawPressRecdangle(QPoint point); void onDrawReleaseRecdangle(QPoint point); void drawPressTriangle(QPoint point); void drawReleaseTriangle(QPoint point); void drawPressEllipse(QPoint point); void drawReleaseEllipse(QPoint point); //各种转到槽 void on_rectangleButton_clicked(); void on_ellipseButton_clicked(); void on_circularButton_clicked(); void on_triangleButton_clicked(); void on_lineButton_clicked(); void on_textButton_clicked(); void on_enlargeButton_clicked(); void on_narrowButton_clicked(); void on_leftButton_clicked(); void on_rightButton_clicked(); void on_frontButton_clicked(); void on_afterButton_clicked(); void on_deleteButton_clicked(); void on_conbButton_clicked(); void on_disperseButton_clicked(); void on_recoveryButton_clicked(); void on_pictrueButton_clicked(); void on_pixmapButton_clicked(); void on_stop_clicked(); void on_run_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include template void setBrushColor(T *item) { //关于更改方块的颜色的模板函数 QColor color = item->brush().color(); color = QColorDialog::getColor(color,NULL,"选择填充颜色"); if(color.isValid()){ //如果存在与此键关联的缓存像素映射,则返回true。否则,如果pixmap被刷新,密钥将不再有效。 item->setBrush(QBrush(color)); } } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); initview();//美化界面 labViewCord = new QLabel("View 坐标:"); labViewCord->setMinimumWidth(150); //设置最小宽度 ui->statusBar->addWidget(labViewCord);//QStatusBar类提供了一个适合显示状态信息的水平条。 labSceneCord= new QLabel("Scene 坐标:"); labSceneCord->setMinimumWidth(150); ui->statusBar->addWidget(labSceneCord); labItemCord = new QLabel("Item 坐标:"); labItemCord->setMinimumWidth(150); ui->statusBar->addWidget(labItemCord); labItemInfo = new QLabel("ItemInfo: "); labItemInfo->setMinimumWidth(200); ui->statusBar->addWidget(labItemInfo); scene = new QGraphicsScene(-300, -200, 600, 200);//创建一个场景 ui->graphicsView->setScene(scene); //与view关联 ui->graphicsView->setCursor(Qt::CrossCursor);//设置鼠标,十字光标,通常用于帮助用户准确选择屏幕上的点。 ui->graphicsView->setMouseTracking(true);//启用了鼠标跟踪,即使没有按下按钮,小部件也会接收鼠标移动事件。 //此属性保留按住鼠标左键时在场景上拖动鼠标的行为。 ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);//将出现一条橡皮筋。拖动鼠标将设置橡皮筋几何体,并选择橡皮筋覆盖的所有项目 // this->setCentralWidget(ui->graphicsView); //将给定的小部件设置为主窗口的中心小部件。 initSlots(); //信号与槽 qsrand(QTime::currentTime().second()); //关于线程的一个函数 } void MainWindow::initview() { //保存图片 ui->pictrueButton->setToolTip(QString("保存图片")); ui->pictrueButton->setIcon(QIcon(":/pictrue/save.png")); //放大 ui->enlargeButton->setToolTip(QString("放大")); ui->enlargeButton->setIcon(QIcon(":/pictrue/enlarge.png")); //缩小 ui->narrowButton->setToolTip(QString("缩小")); ui->narrowButton->setIcon(QIcon(":/pictrue/narrow.png")); //左右转 ui->leftButton->setToolTip(QString("左转")); ui->leftButton->setIcon(QIcon(":/pictrue/rightRotation.png")); ui->rightButton->setToolTip(QString("右转")); ui->rightButton->setIcon(QIcon(":/pictrue/leftRotation.png")); //前面置 ui->frontButton->setToolTip(QString("前置")); ui->frontButton->setIcon(QIcon(":/pictrue/524.bmp")); ui->afterButton->setToolTip(QString("后置")); ui->afterButton->setIcon(QIcon(":/pictrue/522.bmp")); //恢复 ui->recoveryButton->setToolTip(QString("恢复")); ui->recoveryButton->setIcon(QIcon(":/pictrue/toFront.png")); //组合 ui->conbButton->setToolTip(QString("组合")); ui->conbButton->setIcon(QIcon(":/pictrue/con.png")); //打散 ui->disperseButton->setToolTip(QString("打散")); ui->disperseButton->setIcon(QIcon(":/pictrue/dis.png")); //删除 ui->deleteButton->setToolTip(QString("删除")); ui->deleteButton->setIcon(QIcon(":/pictrue/108.bmp")); //图形 ui->circularButton->setIcon(QIcon(":/pictrue/iage/cir.png")); ui->circularButton->setToolTip(QString("圆形")); ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell1.png")); ui->ellipseButton->setToolTip(QString("椭圆")); ui->lineButton->setIcon(QIcon(":/pictrue/iage/line1.png")); ui->lineButton->setToolTip(QString("直线")); ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec1.png")); ui->rectangleButton->setToolTip(QString("矩形")); ui->textButton->setIcon(QIcon(":/pictrue/iage/text.bmp")); ui->textButton->setToolTip(QString("添加文本")); ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri1.png")); ui->triangleButton->setToolTip(QString("三角形")); ui->pixmapButton->setIcon(QIcon(":/pictrue/iage/K1.png")); ui->pixmapButton->setToolTip(QString("添加图片")); } void MainWindow::initSlots() //各种事件的信号与槽 { connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onMouseClicked(QPoint))); connect(ui->graphicsView, SIGNAL(mouseRightClicked(QPoint)), this, SLOT(onMouseRightClicked(QPoint))); connect(ui->graphicsView, SIGNAL(mouseDoubleClick(QPoint)), this, SLOT(onMouseDoubleClick(QPoint))); connect(ui->graphicsView, SIGNAL(mouseMovePoint(QPoint)), this, SLOT(onMouseMovePoint(QPoint))); connect(ui->graphicsView, SIGNAL(keyPress(QKeyEvent*)), this, SLOT(onKeyPress(QKeyEvent*))); connect(ui->preser, SIGNAL(triggered(bool)), this, SLOT(on_pictrueButton_clicked())); connect(ui->out, SIGNAL(triggered(bool)), this, SLOT(close())); } void MainWindow::wheelEvent(QWheelEvent *event) //鼠标滑轮事件 { if(event->delta() > 0){ on_enlargeButton_clicked(); }else{ on_narrowButton_clicked(); } } void MainWindow::onMouseMovePoint(QPoint ponit)//鼠标移动事件,ponit表示view的坐标 { labViewCord->setText(QString::asprintf("View 坐标:%d,%d", ponit.x(), ponit.y())); QPointF pointScene = ui->graphicsView->mapToScene(ponit); //转换到Scene坐标 labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f", pointScene.x(),pointScene.y())); } void MainWindow::onMouseClicked(QPoint point)//鼠标左击事件 { QPointF pointScene = ui->graphicsView->mapToScene(point); //转换到Scene坐标 QGraphicsItem *item = NULL; item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项 if(item != NULL) { QPointF pointItem = item->mapFromScene(pointScene); //转换为绘图项的局部坐标 labItemCord->setText(QString::asprintf("Item 坐标:%.0f,%.0f", pointItem.x(), pointItem.y())); labItemInfo->setText(item->data(ItemDesciption).toString()+", ItemId="+item->data(ItemId).toString()); } } void MainWindow::onMouseRightClicked(QPoint point) //鼠标右击出菜单 { actPoint = point; QPointF pointScene = ui->graphicsView->mapToScene(point); //转换到scene坐标 QGraphicsItem *item = NULL; item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项 if(item == NULL) //没有绘图项 { return; } QMenu *menu = new QMenu(this); menu->addAction(QString("放大")); menu->addAction(QString("缩小")); menu->addAction(QString("左转")); menu->addAction(QString("右转")); menu->addAction(QString("前置")); menu->addAction(QString("后置")); menu->addAction(QString("组合")); menu->addAction(QString("散开")); menu->addAction(QString("删除")); connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(actionTrigger(QAction*))); menu->exec(QCursor::pos()); } void MainWindow::actionTrigger(QAction *act) { if(act->text() == "放大"){ on_enlargeButton_clicked(); }else if(act->text() == "缩小"){ on_narrowButton_clicked(); }else if(act->text() == "左转"){ on_leftButton_clicked(); }else if(act->text() == "右转"){ on_rightButton_clicked(); }else if(act->text() == "前置"){ on_frontButton_clicked(); }else if(act->text() == "后置"){ on_afterButton_clicked(); }else if(act->text() == "组合"){ on_conbButton_clicked(); }else if(act->text() == "散开"){ on_disperseButton_clicked(); }else if(act->text() == "删除"){ on_deleteButton_clicked(); } } void MainWindow::onMouseDoubleClick(QPoint point)//鼠标双击事件,调用相应的对话框,设置填充颜色、字体 { QPointF pointScene = ui->graphicsView->mapToScene(point);//转换到scene的坐标 QGraphicsItem *item = NULL; item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项 if(item == NULL) //没有绘图项 { return; } switch(item->type()) //绘图项的类型 { case QGraphicsRectItem::Type: //矩形框 { //强制类型转换 QGraphicsRectItem *theItem = qgraphicsitem_cast(item); setBrushColor(theItem);//更改颜色的模板函数 break; } case QGraphicsEllipseItem::Type: //椭圆和圆 { QGraphicsEllipseItem *theItem; theItem = qgraphicsitem_cast(item); setBrushColor(theItem); break; } case QGraphicsPolygonItem::Type: //梯形和三角形 { QGraphicsPolygonItem *theItem = qgraphicsitem_cast(item); setBrushColor(theItem); break; } case QGraphicsLineItem::Type: //直线 { QGraphicsLineItem *theItem = qgraphicsitem_cast(item); QPen pen = theItem->pen(); QColor color = theItem->pen().color(); color = QColorDialog::getColor(color, this,"选择线条颜色"); if(color.isValid()) //如果颜色有效,则返回true;否则返回false。 { pen.setColor(color); theItem->setPen(pen); } break; } case QGraphicsTextItem::Type: //文字,设置字体 { QGraphicsTextItem *theItem = qgraphicsitem_cast(item); QFont font = theItem->font(); //QFont类指定用于绘制文本的字体。 bool ok = false; font = QFontDialog::getFont(&ok, font, this, "设置字体"); if(ok) { theItem->setFont(font); } break; } } } void MainWindow::onKeyPress(QKeyEvent *event) { //按键事件 if(scene->selectedItems().count()!=1)//没有选中的绘图项,或选中的多于1个 { return; } QGraphicsItem *item = scene->selectedItems().at(0); if(event->key() == Qt::Key_Delete){//删除 scene->removeItem(item); } else if(event->key() == Qt::Key_Space){ //顺时针旋转 item->setRotation(30+item->rotation());//设置围绕Z轴的顺时针旋转角度(以度为单位)。默认值为0 } else if(event->key() == Qt::Key_PageUp){ //放大 item->setScale(0.1+item->scale()); //设置项目的比例因子。默认比例因子为1.0(即,项目未缩放) } else if(event->key() == Qt::Key_PageDown){ //缩小 item->setScale(-0.1+item->scale()); } else if(event->key() == Qt::Key_Left) { //左移 item->setX(-1+item->x()); } else if(event->key() == Qt::Key_Right){ //右移 item->setX(1+item->x()); } else if(event->key() == Qt::Key_Up){ //上移 item->setY(1+item->y()); } else if(event->key() == Qt::Key_Down){ //下移 item->setY(-1+item->y()); } } void MainWindow::drawPressLine(QPoint point) { qDebug() setZValue(++frontZ); QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标 item->setPos(pointScene.x(), pointScene.y()); item->setData(ItemId,++seqNum); item->setData(ItemDesciption,"直线"); scene->addItem(item); scene->clearSelection(); item->setSelected(true); } void MainWindow::onDrawPressRecdangle(QPoint point) { linePoint = point; } void MainWindow::onDrawReleaseRecdangle(QPoint point) //画矩形 { QGraphicsRectItem *item = new QGraphicsRectItem(-abs(linePoint.x()-point.x())/2, -abs(linePoint.y()-point.y())/2, abs(linePoint.x()-point.x()), abs(linePoint.y()-point.y()));//x,y为左上角的图元局部坐标,图元中心为0,0 item->setBrush(QBrush(Qt::yellow)); //设置初始填充颜色 QPointF oldpoint=ui->graphicsView->mapToScene(linePoint); //转换到Scene坐标 QPointF newpoint=ui->graphicsView->mapToScene(point); //转换到Scene坐标 item->setPos((newpoint.x()-oldpoint.x())/2+oldpoint.x(),(newpoint.y()-oldpoint.y())/2+oldpoint.y()); //设置初始坐标 item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); //设置图形项的属性,例如:可选择、可移动 item->setZValue(++frontZ);//将项目的Z值设置为Z。Z值决定同级(相邻)项目的堆叠顺序。Z值较高的同级项将始终绘制在Z值较低的另一个同级项的顶部。 //自定义数据 item->setData(ItemId, ++seqNum); item->setData(ItemDesciption, "矩形"); scene->addItem(item); // scene->clearSelection(); // 清除当前选择 item->setSelected(true); //初始选择该项目 } void MainWindow::drawPressTriangle(QPoint point) { linePoint = point; } void MainWindow::drawReleaseTriangle(QPoint point) //画三角形 { QGraphicsPolygonItem *item = new QGraphicsPolygonItem; QPolygonF points; //QPolygonF类使用浮点精度提供点向量。 points.append(QPointF(0,0)); //QPointF类使用浮点精度定义平面中的点。 points.append(QPointF(-((linePoint.x()-point.x())/2),(linePoint.y()-point.y()))); points.append(QPointF((linePoint.x()-point.x())/2,linePoint.y()-point.y())); item->setPolygon(points); QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标 item->setPos(pointScene.x()-(point.x()-linePoint.x())/2, pointScene.y()); item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); item->setBrush(QBrush(Qt::magenta)); item->setZValue(++frontZ); item->setData(ItemId, ++seqNum); item->setData(ItemDesciption, "三角形"); scene->addItem(item); scene->clearSelection(); item->setSelected(true); } void MainWindow::drawPressEllipse(QPoint point) { linePoint = point; } void MainWindow::drawReleaseEllipse(QPoint point) //画椭圆 { QGraphicsEllipseItem *item = new QGraphicsEllipseItem(0, 0, linePoint.x()-point.x(), linePoint.y()-point.y()); item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); item->setBrush(QBrush(Qt::blue)); item->setZValue(++frontZ); QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标 item->setPos(pointScene.x(), pointScene.y()); item->setData(ItemId, ++seqNum); item->setData(ItemDesciption, "椭圆"); scene->addItem(item); scene->clearSelection(); item->setSelected(true); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_rectangleButton_clicked() //添加矩形 { if(isrectangle){ connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onDrawPressRecdangle(QPoint))); connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(onDrawReleaseRecdangle(QPoint))); ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec.png")); isrectangle = false; }else{ ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onDrawPressRecdangle(QPoint))); ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(onDrawReleaseRecdangle(QPoint))); ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec1.png")); isrectangle = true; } qDebug() graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressEllipse(QPoint))); connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseEllipse(QPoint))); ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell.png")); isEllipse = false; }else{ ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressEllipse(QPoint))); ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseEllipse(QPoint))); ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell1.png")); isEllipse = true; } } void MainWindow::on_circularButton_clicked() //添加圆形 { QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50, -50, 100, 100); item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); item->setBrush(QBrush(Qt::cyan)); //青色 item->setZValue(++frontZ); item->setPos(-50+qrand()%100, -50+(qrand()%100)); item->setData(ItemId, ++seqNum); item->setData(ItemDesciption, "圆形"); scene->addItem(item); scene->clearSelection(); item->setSelected(true); } void MainWindow::on_triangleButton_clicked() //添加三角形 { if(isTriangle){ connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressTriangle(QPoint))); connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseTriangle(QPoint))); ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri.png")); isTriangle = false; }else{ ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressTriangle(QPoint))); ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseTriangle(QPoint))); ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri1.png")); isTriangle = true; } } void MainWindow::on_lineButton_clicked() //添加直线 { if(isline){ connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressLine(QPoint))); connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseLine(QPoint))); ui->lineButton->setIcon(QIcon(":/pictrue/iage/line.BMP")); isline = false; }else{ ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressLine(QPoint))); ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseLine(QPoint))); ui->lineButton->setIcon(QIcon(":/pictrue/iage/line1.png")); isline = true; } qDebug() font(); font.setPointSize(20); font.setBold(true); item->setFont(font); item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); item->setPos(-50+(qrand()%100), -50+(qrand()%100)); item->setZValue(++frontZ); item->setData(ItemId, ++seqNum); item->setData(ItemDesciption, "文字"); scene->addItem(item); scene->clearSelection(); item->setSelected(true); } void MainWindow::on_enlargeButton_clicked() //放大 { int cnt = scene->selectedItems().count(); if(cnt == 1){ QGraphicsItem *item; item = scene->selectedItems().at(0); item->setScale(0.1+item->scale()); // 比例因子 }else{ ui->graphicsView->scale(1.1,1.1); //按(sx,sy)缩放当前视图变换,正常比例为1,1。 } } void MainWindow::on_narrowButton_clicked() //缩小 { int cnt = scene->selectedItems().count(); if(cnt == 1){ QGraphicsItem *item; item = scene->selectedItems().at(0); item->setScale(-0.1+item->scale()); }else{ ui->graphicsView->scale(0.9,0.9); //正常比例为1,1 } } void MainWindow::on_leftButton_clicked() //左转 { int cnt = scene->selectedItems().count(); if(cnt == 1){ QGraphicsItem *item =scene->selectedItems().at(0); item->setRotation(-30+item->rotation()); }else{ ui->graphicsView->rotate(-30); //rotate:顺时针旋转当前视图变换角度。 } } void MainWindow::on_rightButton_clicked() //右转 { int cnt = scene->selectedItems().count(); //返回所有当前选定项目的列表 if(cnt == 1){ QGraphicsItem *item = scene->selectedItems().at(0); item->setRotation(30+item->rotation()); }else{ ui->graphicsView->rotate(30); } } void MainWindow::on_frontButton_clicked() //前置 { int cnt = scene->selectedItems().count(); if(cnt > 0){ //只处理第一个选中项 QGraphicsItem *item = scene->selectedItems().at(0); item->setZValue(++frontZ); } } void MainWindow::on_afterButton_clicked() //后置 { int cnt = scene->selectedItems().count(); if(cnt > 0){ QGraphicsItem *item = scene->selectedItems().at(0); item->setZValue(--backZ); } } void MainWindow::on_deleteButton_clicked() //删除 { int cnt = scene->selectedItems().count(); if(cnt > 0){ int i = 0; for(i=0; i < cnt; i++){ QGraphicsItem *item = scene->selectedItems().at(0); scene->removeItem(item); //删除绘图项 } } } void MainWindow::on_conbButton_clicked() //组合 { int cnt = scene->selectedItems().count(); if(cnt > 1){ QGraphicsItemGroup *group = new QGraphicsItemGroup;//QGraphicsItemGroup类提供了一个容器,将一组项视为单个项。 // QGraphicsItemGroup是一种特殊类型的复合项,它将自身及其所有子项视为一个项(即,所有子项的所有事件和几何图形都合并在一起)。 scene->addItem(group); for(int i=0; iselectedItems().at(0); item->setSelected(false);//清除虚线 item->clearFocus(); // group->addToGroup(item); //添加到组合去 } group->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); group->setZValue(++frontZ); scene->clearSelection(); group->setSelected(true); } } void MainWindow::on_disperseButton_clicked() //打散 { int cnt = scene->selectedItems().count(); if(cnt == 1){ QGraphicsItemGroup *group; group=(QGraphicsItemGroup*)scene->selectedItems().at(0); scene->destroyItemGroup(group); //将组中的所有项目重设为组的父项目,然后从场景中移除组,最后将其删除。项目的位置和变换从组映射到组的父对象。 } } void MainWindow::on_recoveryButton_clicked() //视图恢复 { int cnt = scene->selectedItems().count(); if(cnt == 1){ QGraphicsItem *item = scene->selectedItems().at(0); item->resetTransform(); }else{ ui->graphicsView->resetTransform();//将视图转换重置为标识矩阵。 } } void MainWindow::on_pictrueButton_clicked() //保存图片 { QPixmap map = ui->graphicsView->grab(); QString filename; filename = QFileDialog::getSaveFileName(this, tr("保存图片"), "", tr("Image Files(*.png *.jpg *.bmp)")); if(!filename.isNull()){ QFile *file = new QFile(filename); file->open(QIODevice::ReadWrite); map.save(file); file->close(); } } void MainWindow::on_pixmapButton_clicked() //添加图片 { QGraphicsPixmapItem *pixmap = scene->addPixmap(QPixmap(QFileDialog::getOpenFileName(this, "Open", "./", "*.png"))); pixmap->setPos(0,0); pixmap->setZValue(++frontZ); pixmap->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); pixmap->setData(ItemId, ++seqNum); pixmap->setData(ItemDesciption, "图片"); scene->addItem(pixmap); scene->clearSelection(); pixmap->setSelected(true); } void MainWindow::on_stop_clicked() { int cnt = scene->selectedItems().count(); if(cnt > 0){ int i = 0; for(i=0; i < cnt; i++){ QGraphicsItem *item = scene->selectedItems().at(i); item->setFlags(QGraphicsItem::ItemStopsFocusHandling | QGraphicsItem::ItemIsSelectable); } } } void MainWindow::on_run_clicked() { int cnt = scene->selectedItems().count(); if(cnt > 0){ int i = 0; for(i=0; i < cnt; i++){ QGraphicsItem *item = scene->selectedItems().at(i); item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable); } } }

下面是对视图进行重写,在ui界面对控件进行提升

 mygraphicsview.h

#ifndef MYGRAPHICSVIEW_H #define MYGRAPHICSVIEW_H #include #include class MyGraphicsView : public QGraphicsView { Q_OBJECT public: MyGraphicsView(QWidget *parent = 0); QColor BackgroundColor = QColor(53,53,53); //背景颜色 QColor FineGridColor = QColor(0,60,0); //细网格颜色 QColor CoarseGridColor = QColor(120,25,25); //粗网格颜色 protected: void mouseMoveEvent(QMouseEvent *event); //鼠标移动事件 void mousePressEvent(QMouseEvent *event); //鼠标按下事件 void mouseReleaseEvent(QMouseEvent *event); //鼠标释放事件 void mouseDoubleClickEvent(QMouseEvent *event); //鼠标双击事件 void keyPressEvent(QKeyEvent *event); //键盘按下事件 void drawBackground(QPainter *painter, const QRectF &r); //改变背景颜色 signals: void mouseMovePoint(QPoint point); //鼠标移动坐标 void mouseClicked(QPoint point); //鼠标左击按下坐标 void mouseRelease(QPoint point); //鼠标释放坐标 void mouseRightClicked(QPoint point);//鼠标右击按下坐标 void mouseDoubleClick(QPoint point); //鼠标双击坐标 void keyPress(QKeyEvent *event); //键盘按下 }; #endif // MYGRAPHICSVIEW_H

mygraphicsview.cpp

#include "mygraphicsview.h" #include #include #include #include MyGraphicsView::MyGraphicsView(QWidget *parent):QGraphicsView(parent) { //滚动条隐藏 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //绘图抗锯齿 setRenderHints(QPainter::Antialiasing); //设置背景颜色 setBackgroundBrush(BackgroundColor); } void MyGraphicsView::mouseMoveEvent(QMouseEvent *event) { //鼠标移动事件 QPoint point = event->pos(); //保存鼠标移动的坐标 emit mouseMovePoint(point); //发送信号 QGraphicsView::mouseMoveEvent(event); //使父类的事件不受影响 } void MyGraphicsView::mousePressEvent(QMouseEvent *event) { //鼠标按下事件 if(event->button() == Qt::LeftButton) //判断鼠标按下的是左键 { QPoint point = event->pos(); //保存View此时的坐标 emit mouseClicked(point); //发送信号 }else if(event->button() == Qt::RightButton){ //判断鼠标按下的是右键 QPoint poind = event->pos(); emit mouseRightClicked(poind); } QGraphicsView::mousePressEvent(event); } void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) //判断鼠标释放的是左键 { QPoint point = event->pos(); //保存View此时的坐标 emit mouseRelease(point); //发送信号 } QGraphicsView::mouseReleaseEvent(event); } void MyGraphicsView::mouseDoubleClickEvent(QMouseEvent *event) { //鼠标双击事件 if(event->button() == Qt::LeftButton) { QPoint point = event->pos();//保存View此时的坐标 emit mouseDoubleClick(point); //发送信号 } QGraphicsView::mouseDoubleClickEvent(event); } void MyGraphicsView::keyPressEvent(QKeyEvent *event) { emit keyPress(event); QGraphicsView::keyPressEvent(event); } void MyGraphicsView::drawBackground(QPainter *painter, const QRectF &r) { QGraphicsView::drawBackground(painter, r); auto drawGrid = [&](double gridStep){ QRect windowRect = rect(); QPointF tl = mapToScene(windowRect.topLeft()); QPointF br = mapToScene(windowRect.bottomRight()); double left = std::floor(tl.x() / gridStep - 0.5); double right = std::floor(br.x() / gridStep + 1.0); double bottom = std::floor(tl.y() / gridStep - 0.5); double top = std::floor(br.y() / gridStep + 1.0); //垂直线 for(int xi = int(left); xi drawLine(line); } //水平线 for(int yi = int(bottom); yidrawLine(line); } }; QPen pfine(FineGridColor, 1.0); painter->setPen(pfine); drawGrid(15); QPen p(CoarseGridColor, 1.0); painter->setPen(p); drawGrid(150); } 结尾

       这是学习QT之后跟着写的一个小项目,很多地方还有bug,这篇文章只能做一个参考,谢谢!如对你有用,可以点一个小小赞,非常感谢!

       注:如有侵权,请联系本人删除此文章。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3